/**
 * ds18b20.h - DS18B20 功能封装 (头文件)
 * by Nixsawe
 * 2022-1-5 ~ 2022-1-7
 * 
 * 不支持寄生电源模式
 */

#ifndef _DS18B20_H_
#define _DS18B20_H_

#include<atmel/at89x52.h>
#include<intrins.h>

// 定义总线
#ifndef DS18B20_DATA_IO
#define DS18B20_DATA_IO P3_7
#endif /* DS18B20_DATA_IO */

// 定义基本类型
typedef unsigned char DS18B20_TEMP_T;

// 定义 ROM 编码类型
typedef union {
	struct {
		unsigned char family_code;
		unsigned char serial_number[6];
		unsigned char crc;
	} rom_data;
	unsigned char rom_code[8];
} DS18B20_ROM_CODE;

// 定义暂存器空间
typedef union {
	struct {
		DS18B20_TEMP_T temp_low;		// 温度低字节
		DS18B20_TEMP_T temp_high;	// 温度高字节

		// th、tl、config 三个字节与 EEPROM 三个字节对应
		DS18B20_TEMP_T th;			// TH 寄存器（和 TL 一起用于温度报警）
		DS18B20_TEMP_T tl;			// TL 寄存器
		unsigned char config;		// 配置寄存器

		unsigned char reserved_ff;	// 保留字，值为 0xff
		unsigned char reserved;		// 保留字，值不确定
		unsigned char reserved_10;	// 保留字，值为 0x10

		unsigned char crc;			// 前 8 字节的 CRC 校验值
	} pad_data;
	unsigned char pad_bytes[9];
} DS18B20_SCRATCHPAD_PAD;

// 温度值
#define DS18B20_TEMP(dat) ((DS18B20_TEMP_T)(dat))
#define DS18B20_TEMP_INT(high,low) ((signed int)(signed char)((DS18B20_TEMP(high) << 4) | (DS18B20_TEMP(low) >> 4)))
#define DS18B20_TEMP_FLOAT(high,low) ((float)(signed short)((((unsigned short)DS18B20_TEMP(high)) << 8) | DS18B20_TEMP(low)) / 16)
#define DS18B20_INVALID_TEMP_INT ((signed int)0x8000)
#define DS18B20_INVALID_TEMP_FLOAT ((float)(1.0 / 32))

// 配置寄存器位定义
#define DS18B20_CONF_R0 0x20
#define DS18B20_CONF_R1 0x40
#define DS18B20_CONFIG_BYTE(mask) (0x1F | (mask))
#define DS18B20_CONFIG_RESOLUTION(bits) DS18B20_CONFIG_BYTE((bits - 9) << 5)
// 有两种使用方式
//   DS18B20_CONFIG_BYTE(DS18B20_CONF_R0)
//   DS18B20_CONFIG_RESOLUTION(10)

// ROM 命令
#define DS18B20_CMD_SEARCH_ROM   0xF0
#define DS18B20_CMD_READ_ROM     0x33
#define DS18B20_CMD_MATCH_ROM    0x55
#define DS18B20_CMD_SKIP_ROM     0xCC
#define DS18B20_CMD_ALARM_SEARCH 0xEC

// 功能命令
#define DS18B20_CMD_CONVERT_T    0x44
#define DS18B20_CMD_WRITE_PAD    0x4E
#define DS18B20_CMD_READ_PAD     0xBE
#define DS18B20_CMD_COPY_PAD     0x48
#define DS18B20_CMD_RECALL_EE    0xB8
#define DS18B20_CMD_READ_POWER   0xB4

// 函数原型
unsigned char ds18b20_reset();
void ds18b20_write_bit(unsigned char dat);
unsigned char ds18b20_read_bit();
void ds18b20_write_byte(unsigned char dat);
unsigned char ds18b20_read_byte();

unsigned char ds18b20_read_rom(DS18B20_ROM_CODE * rom);
void ds18b20_match_rom(DS18B20_ROM_CODE * rom);
void ds18b20_skip_rom();

unsigned char ds18b20_wait_finish(int wait_ms);
void ds18b20_convert();
unsigned char ds18b20_convert_sync();
void ds18b20_write_pad(DS18B20_TEMP_T th, DS18B20_TEMP_T tl, unsigned char cfg);
unsigned char ds18b20_read_pad(DS18B20_SCRATCHPAD_PAD * pad);
void ds18b20_copy_pad();
unsigned char ds18b20_copy_pad_sync();
void ds18b20_recall_ee();
unsigned char ds18b20_recall_ee_sync();
unsigned char ds18b20_read_power();

unsigned char ds18b20_init(DS18B20_TEMP_T th, DS18B20_TEMP_T tl, unsigned char bits);
unsigned char ds18b20_read_temp_bytes(DS18B20_TEMP_T * high, DS18B20_TEMP_T * low);
unsigned char ds18b20_read_user_bytes(unsigned char * byte1, unsigned char * byte2);
signed int ds18b20_read_int_temp();
float ds18b20_read_float_temp();

// 函数别名
#define ds18b20_presence ds18b20_reset
#define ds18b20_write_config ds18b20_write_pad
#define ds18b20_save ds18b20_copy_pad_sync
#define ds18b20_load ds18b20_recall_ee_sync
#define ds18b20_external_power ds18b20_read_power

#endif /* _DS18B20_H_ */
